"""
Problem 60: https://projecteuler.net/problem=60

质数3, 7, 109, 和 673是值得注意的。
将其中任意两个质数以任何顺序相连接产生的结果都是质数。
例如，取7和109，连接而成的7109和1097都是质数。
这四个质数的和是792，这也是满足这个性质的四个质数集合的最小总和。

找出满足这个性质的五个质数的集合中，集合数之和最小的。算出这个最小的和。
"""

# _*_ conding:UTF-8 _*_
'''
@author = Kuperain
@email = kuperain@aliyun.com
@IDE = VSCODE Python3.8.3
@creat_time = 2022/5/19
'''


from commonfuncs import primefunctools as pf
pt = pf.primesTable()


def isPrime(n):
    try:
        return pt[n]
    except IndexError:
        return pf.isPrime(n)


def combinsisprime(newNum, *nums):
    if not isPrime(newNum):
        return False

    if newNum % 3 != nums[0] % 3:
    # if euqal, (nums[0] -- newNum) % 3 == 0, is not prime
    # so, all in nums must be congruences 
        # print(f'{newNum} ruled out by 3')
        return False
    
    if 100<=newNum<=999:
    # for (num -- newNum) where newNum has 3 digits, 
    # if (num-newNum) % 7 == 0, (newNum -- num) % 7 == 0
        for num in nums:
            if (num - newNum) % 7 == 0:
                # print(f'{newNum} ruled out by 7')
                return False
    '''
    for num in nums:
        diff = len(str(num)) - len(str(newNum))
        if diff == 1 or diff == 3:
            print(f'{newNum} ruled out by 11')
            if num%11 == newNum%11:
                return False
    '''

    for num in nums:
        num1 = int(str(num)+str(newNum))
        if not isPrime(num1):
            return False
        num2 = int(str(newNum)+str(num))
        if not isPrime(num2):
            return False

    return True


def solution(digitslimit: int = 4) -> int:
    maxNum = 10**digitslimit
    for d1 in range(3, maxNum, 2):  # impossible be 2
        if not isPrime(d1):
            continue
        for d2 in range((d1+1) if (d1+1) % 2 else d1+2, maxNum, 2):
            if not combinsisprime(d2, d1):
                continue
            for d3 in range((d2+1) if (d2+1) % 2 else d2+2, maxNum, 2):
                if not combinsisprime(d3, d1, d2):
                    continue
                for d4 in range((d3+1) if (d3+1) % 2 else d3+2, maxNum, 2):
                    if not combinsisprime(d4, d1, d2, d3):
                        continue
                    for d5 in range((d4+1) if (d4+1) % 2 else d4+2, maxNum, 2):
                        if combinsisprime(d5, d1, d2, d3, d4):
                            print(d1, d2, d3, d4, d5)
                            return sum([d1, d2, d3, d4, d5])
    return


if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=False)

    print(solution())
    # (13, 5197, 5701, 6733, 8389)
    # 26033
